﻿using System;
using System.Data;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using Dimok.BlackBook;
using Data.LINQ;
/// <summary>
/// Summary description for Lib
/// </summary>
public static class Lib {

	#region Car Price
	public struct CarPrice {
		public int Price;
		public int TypeID;
		public CarPrice(int Price, int TypeID) {
			this.Price = Price;
			this.TypeID = TypeID;
		}
	}
	public static CarPrice GetCarPrice(string VIN, int Mileage, string State, string Description, int BookValueTypeID) {
		var mb = new MotoBank();
		var bp_vt = mb.ts_CarBookProvider_ValueTypes.Single(r => r.ID == BookValueTypeID);
		if (bp_vt.ProviderID == 1) {
			var dsPriceInfo = BlackBook.LoadPriceInfo(VIN, State, Mileage);
			var price = dsPriceInfo.BookValue.Cast<PriceInfoDS.BookValueRow>()
				.Where(r => r.Price + r.MileageAddOn > 0)
				.Select(r => new { Price = r.Price + r.MileageAddOn, Type = (int)Enum.Parse(typeof(PriceType), r.Type, true) })
				.Select(r => new { Price = r.Price, Type = r.Type, TypeDiff = r.Type - bp_vt.TypeID })
				.OrderByDescending(r => r.TypeDiff == 0).ThenBy(r => r.TypeDiff)
				.DefaultIfEmpty()
				.First();
			if (price != null) {
				int bookValueTypeID = mb.ts_CarBookProvider_ValueTypes
					.Single(r => r.ProviderID == bp_vt.ProviderID && r.TypeID == price.Type).ID;
				return new CarPrice(price.Price, bookValueTypeID);
			} else if (bp_vt.XRefID.HasValue && bp_vt.XRefID.Value > 0)
				return GetCarPrice(VIN, Mileage, State,Description, bp_vt.XRefID.Value);
		}
		if (bp_vt.ProviderID == 4) {
			Manheim.ManheimPriceDS ds = Manheim.ManheimClient.Activate().GetPriceByVIN("SE", VIN, Mileage, Description);
			var price = ds.Price.Cast<Manheim.ManheimPriceDS.PriceRow>().SingleOrDefault(r => r.Type == (bp_vt.TypeID+""));
			return price == null ? new CarPrice(-1, 0) : new CarPrice(price.Price, BookValueTypeID);
		}
		throw new NotSupportedException("BookValueTypeID:" + BookValueTypeID + " is not supported.");
	}
	#endregion

	#region Tracer
	public static void TraceIn(this Control control, string message) { control.TraceMe("<=====" + message,1); }
	public static void TraceOut(this Control control, string message) { control.TraceMe("=====>" + message,1); }
	public static void TraceMe(this Control control, string message) { control.TraceMe(message, 1); }
	public static void TraceMe(this Control control, string message,int frame) {
		var mi = Dimok.Common.GetMethod(frame+1);
		string parent = (control.NamingContainer ?? control.Page).GetType().Name;
		control.Page.Trace.Warn(parent + "." + mi.DeclaringType.Name + "." + mi.Name + ":" + message);
	}
	#endregion

	#region ADS
	private static Dimok.Data.ADsUser.th_AdsUserDataTable _users = null;
	public static Dimok.Data.ADsUser.th_AdsUserDataTable UserList() {
		if (_users == null) {
			Data.DataSources.UsersDataSource dsoUsers = new Data.DataSources.UsersDataSource();
			dsoUsers.ShowProfiles = true;
			_users = dsoUsers.SelectEx();
		}
		return _users;
	}
	#endregion

	#region Format
	public static string FormatNote(string Note,int MaxLineLength) {
		return Regex.Replace(Regex.Replace(Note, "[.]{2,}", "\n"),".{"+MaxLineLength+"}","$0\n");
	}
	public static string FormatPhone(object Phone) { return FormatPhone(Phone, ""); }
	public static string FormatPhone(object Phone, string DefaultValue) {
		List<string> phones = new List<string>();
		Regex re = new Regex(@"(?<p1>\d{3})\D*(?<p2>\d{3})\D*(?<p3>\d{4})\D*$", RegexOptions.RightToLeft);
		foreach (string phone in (Phone + "").Split('\n'))
			phones.Add(re.Replace(phone, "$1-$2-$3"));
		string sPhone = string.Join("\n", phones.ToArray());
		return sPhone == "" ? DefaultValue : sPhone;
	}
	public static string FormatSSN(object ssn) { return FormatSSN(ssn, ""); }
	public static string FormatSSN(object ssn, string DefaultValue) {
		if ((ssn + "") == "") return DefaultValue;
		Regex re = new Regex(@"(?<p1>\d{3})\D*(?<p2>\d{2})\D*(?<p3>\d{4})\D*$", RegexOptions.RightToLeft);
		return re.Replace(ssn+"", "$1-$2-$3");
	}
	//public static string FormatPhone(object Phone) {
	//  return Regex.Replace(Phone+"", @"(?<p1>\d{3})\D*(?<p2>\d{3})\D*(?<p3>\d{4})\D*$", "$1-$2-$3", RegexOptions.RightToLeft);
	//}
	#endregion
	

	#region UserName
	public static string GetUserFullName(string userPath) {
		return Dimok.User.UserObject.CurrentUserDomain + "\\" + GetUserName(userPath);
	}

	public static string GetUserName() {
		return GetUserName(HttpContext.Current.User.Identity.Name);
	}
	public static string GetUserName(string userPath) {
		return Regex.Match(userPath, @"[^\\]+$").Value;
	}
	#endregion

	#region Make (int,decimal..)
	public static int MakeInt(object o) { return Dimok.Common.ParseInt(o); }
	public static decimal MakeDecimal(object o) { return Dimok.Common.ParseDecimal(o); }
	public static string Substring(object text, int length) {
		return (text + "").Length <= length ? text + "" : (text + "").Substring(0, length);
	}
	public static string MakeIDsXml(string IDs) {
		return "<ID>" + string.Join("</ID><ID>", IDs.Split(',')) + "</ID>";
	}
	#endregion

	#region Get/Set Propertied
	public static object GetProperty(object o, string p) {
		while (o != null) {
			System.Reflection.PropertyInfo pi = o.GetType().GetProperty(p);
			if (pi != null) return pi.GetValue(o, null);
			System.Reflection.FieldInfo fi = o.GetType().GetField(p);
			if (fi != null) return fi.GetValue(o);
			o = ((Control)o).NamingContainer;
		}
		throw new NotImplementedException("Property " + p + " is not implemented.");
	}
	public static void SetProperty(object o, string p, object v) {
		System.Reflection.PropertyInfo pi = o.GetType().GetProperty(p);
		if (pi != null) pi.SetValue(o, v, new object[] { });
		else {
			System.Reflection.FieldInfo fi = o.GetType().GetField(p);
			if (fi == null) throw new NotImplementedException("Property " + p + " is not implemented in " + o.GetType().FullName + ".");
			fi.SetValue(o, v);
		}
	}
	#endregion

}
